from flask_restplus import Resource, Namespace, fields, marshal, reqparse
from common.decorators import catch_error
from common.responses import ok
from common import constant
from common.response_model import base_model, pagination_model
from common.request_parser import get_parser as base_get_parser
from app.user.decorators import token_required
from app.customer.model import Customer
from app.customer import dao

api = Namespace('customer')

# ---------- model ----------
customer_model = base_model.inherit('customer_model', {
    "customer_type": fields.Integer(description='类型'),
    "address": fields.String(description='地址'),
    "phone": fields.String(description='手机号'),
    'email': fields.String(description='邮箱'),
    "discount": fields.Float(description='折扣'),
    'contact': fields.String(description='联系人信息'),
})
customer_paginate_model = pagination_model.inherit('customer_paginate_model', {
    "items": fields.Nested(customer_model)
})

# ---------- create parser ----------
create_parser = reqparse.RequestParser()
create_parser.add_argument('name', type=str, required=True, help='商品名称')
create_parser.add_argument('short_name', type=str, help='名称拼音缩写，默认不用填写')
create_parser.add_argument('customer_type', type=int,
                           choices=[constant.CustomerType.CLIENT.value, constant.CustomerType.SUPPLIER.value],
                           required=True,
                           help='客户类别')
create_parser.add_argument('notes', type=str, help='备注')
create_parser.add_argument('is_active', type=bool, choices=[True, False], help='是否启用')

# ---------- get parser ----------
get_parser = base_get_parser.copy()
get_parser.replace_argument('sorted_by', type=str, choices=[
    'name', 'id'
], default='id', help='sorted_by')
get_parser.add_argument(
    'customer_type', type=int,
    choices=[constant.CustomerType.CLIENT.value, constant.CustomerType.SUPPLIER.value],
    help='客户类别')


class CustomersResource(Resource):
    @catch_error
    @token_required
    @api.expect(create_parser)
    def post(self):
        """创建"""
        args = create_parser.parse_args()
        new_obj = Customer.create(**args, commit=True)
        return ok(data=marshal(new_obj, customer_model),
                  message='create success')

    @catch_error
    @token_required
    @api.expect(get_parser)
    def get(self):
        """获取列表"""
        args = get_parser.parse_args()
        pagination = dao.get_by_page(**args)
        return ok(data=marshal(pagination, customer_paginate_model),
                  message='get success')


# ---------- put parser ----------
put_parser = create_parser.copy()
put_parser.replace_argument(
    'customer_type', type=int,
    choices=[constant.CustomerType.CLIENT.value, constant.CustomerType.SUPPLIER.value],
    help='客户类别')


class CustomerResource(Resource):
    @catch_error
    @token_required
    def get(self, obj_id):
        """获取"""
        obj = Customer.query.filter_by(id=obj_id).first()
        return ok(data=marshal(obj, customer_model),
                  message='get success')

    @catch_error
    @token_required
    @api.expect(put_parser)
    def put(self, obj_id):
        """更新"""
        args = put_parser.parse_args()
        for key in list(args.keys()):
            if args.get(key) is None:
                del args[key]
        obj = Customer.query.filter_by(id=obj_id).first()
        obj.update(**args, commit=True)
        return ok(data=marshal(obj, customer_model),
                  message='update success')

    @catch_error
    @token_required
    def delete(self, obj_id):
        """删除"""
        obj = Customer.query.filter_by(id=obj_id).first()
        delete_id = obj.hard_delete(commit=True)
        return ok(
            data={
                'id': delete_id
            },
            message='delete success')


# --------- route ----------
api.add_resource(CustomersResource, '/customers')
api.add_resource(CustomerResource, '/customers/<int:obj_id>')

# 注册 response 文档
api.models[customer_model.name] = customer_model
